<?php


namespace app\shop\service\until;


use app\enterprise\model\Message;
use app\enterprise\model\User;
use app\manage\model\Config;
use app\shop\model\file\FileModel;
use app\shop\service\BaseService;
use think\facade\App;
use think\facade\Filesystem;
use think\facade\Log;
use think\facade\Request;
use think\File;

class FileService extends BaseService
{
    protected $disk = '';
    protected $url = '';

    public static function getInstance()
    {
        return new FileModel();
    }

    public function __construct()
    {
        $this->model = new FileModel();
        $this->disk = env('filesystem.driver', 'local');
        $this->url = getDiskUrl() . '/';
    }

    public static function getFullUrl($path)
    {
        if (!$path) {
            return '';
        }
        return getDiskUrl() . $path;
    }

    public static function getFullUrlById($id)
    {
        $info = self::getInstance()->find($id);
        return self::getFullUrl($info['src']);
    }
    /**
     * 文件上传
     * @param $uid
     * @param $data
     * @param $path
     * @param string $prefix
     * @param bool $fileObj
     * @return array|void
     * @throws \Exception
     */
    public function upload($uid, $data, $path, $prefix = "", $fileObj = true, $useType = 0)
    {
        try {
            $message = $data['message'] ?? '';
            if ($message) {
                $message = json_decode($message, true);
            }
            if ($fileObj) {
                $filePath = $path;
            } else {
                $filePath = new File($path);
            }

            $info = $this->getFileInfo($filePath, $path, $fileObj);

            if ($info['ext'] == '' && $message) {
                $pathInfo = pathinfo($message['fileName'] ?? '');
                $info['ext'] = $pathInfo['extension'];
                $info['name'] = $message['fileName'] ?? '';
            }
            $conf = Config::where(['name' => 'fileUpload'])->value('value');

            if ($conf['size'] * 1024 * 1024 < $info['size']) {
                throw new \Exception('文件大小超过限制');
            }
            // 兼容uniapp文件上传
            if ($info['ext'] == '' && isset($data['ext'])) {
                $info['ext'] = $data['ext'];
            }
            $info['ext'] = strtolower($info['ext']);
            if (!in_array($info['ext'], $conf['fileExt'])) {
                throw new \Exception('文件格式不支持');
            }
            $fileType = getFileType($info['ext']);
            if ($fileType == 2) {
                $fileCate = "image";
            } elseif ($fileType == 3) {
                $msgType = $message['type'] ?? '';
                // 如果是语音消息，类型才为语音，否者为文件，主要是兼容发送音频文件
                if ($msgType == 'voice') {
                    $fileCate = "voice";
                } else {
                    $fileCate = "file";
                }
            } elseif ($fileType == 4) {
                $fileCate = "video";
            } else {
                $fileCate = "file";
            }
            if (!$prefix) {
                $prefix = $fileCate . '/' . $uid . '/' . date('Y-m-d') . "/";
            }
            $name = str_replace('.' . $info['ext'], '', $info['name']);
            $file = FileModel::where(['md5' => $info['md5']])->find();


            // 判断文件是否存在，如果有则不再上传
            if (!$file) {
                $newName = uniqid() . '.' . $info['ext'];
                $object = $prefix . $newName;

//                $savename = Filesystem::disk('local')->putFile( 'upload', $filePath);
                if ($this->disk == 'local') {
//                    $object = 'storage/' . $savename;
                    $object = 'storage/' . $object;
                }else{
//                    $filePath = public_path() . "storage/" . $savename;
//                    $oss = new OssService();
//                    $oss->uploadFile($object,$filePath);
                }

//                Filesystem::putFileAs($prefix, $filePath, $newName);
                Filesystem::disk($this->disk)->putFileAs($prefix, $filePath, $newName);
            } else {
                $object = $file['src'];
            }
            // 把左边的/去掉再加上，避免有些有/有些没有
            $object = '/' . ltrim($object, '/');
            $poster = '';
            if ($fileCate == 'video') {
                if ($this->disk == 'aliyun') {
                    $poster = $this->url . $object . '?x-oss-process=video/snapshot,t_1000,m_fast,w_800,f_png,ar_h';
                } else {
                    $poster = 'https://im.file.raingad.com/static/image/video.png';
                }
            }
            $ret = [
                "src" => $object,
                "name" => $name,
                "cate" => $fileType,
                "size" => $info['size'],
                "md5" => $info['md5'],
                "file_type" => $info['mime'],
                "ext" => $info['ext'],
                "type" => $fileCate,
                'user_id' => $uid,
                'use_type' => $useType,
                'poster' => $poster
            ];
            if (!$file) {
                $file = new FileModel;
                $file->save($ret);
            }
            $ret['file_id'] = $file->file_id;
            if (!$message) {
                return $ret;
            }
            // 自动获取视频第一帧,视频并且是使用的阿里云
            if ($message['type'] == 'video') {
                if ($this->disk == 'aliyun') {
                    $message['extends']['poster'] = $this->url . $ret['src'] . '?x-oss-process=video/snapshot,t_1000,m_fast,w_800,f_png,ar_h';
                } else {
                    $message['extends']['poster'] = 'https://im.file.raingad.com/static/image/video.png';
                }
            }
            // 如果发送的文件是图片、视频、音频则将消息类型改为对应的类型
            if (in_array($fileType, [2, 3, 4])) {
                $message['type'] = $fileCate;
            }
            if ($message['type'] == 'image') {
                $extends = $this->getImageSizeInfo($info['path']);
                $message['extends'] = $extends;
            }


            $message['content'] = $ret['src'];
            $message['file_id'] = $ret['file_id'] ?? 0;
            $message['file_cate'] = $fileType;
            $message['file_size'] = $info['size'];
            $message['file_name'] = $name . '.' . $info['ext'];
            $message['user_id'] = $uid;
            $data = Message::sendMessage($message);
            return $data;
        } catch (\Exception $exception) {
            throw new \Exception($exception->getMessage());
        }
    }


    // 获取上传文件的信息
    protected function getFileInfo(File $file, $path, $isObj = false)
    {
        $info = [
            'path' => $file->getRealPath(),
            'size' => $file->getSize(),
            'mime' => $file->getMime(),
            'ext' => $file->extension(),
            'md5' => $file->md5(),
        ];
        if ($isObj) {
            $info['name'] = $file->getOriginalName();
        } else {
            // 根据路径获取文件名
            $pathInfo = pathinfo($path);
            $info['name'] = $pathInfo['basename'];
        }
        return $info;

    }

    // 上传图片
    public function uploadImage()
    {
        $param = request::param();
        try {
            $file = request()->file('file');
            $info = $this->upload($param, $file, 'image/' . date('Y-m-d') . '/');
            $url = $this->url . $info['src'];
            return success("上传成功", $url);
        } catch (\Exception $e) {
            return error($e->getMessage());
        }
    }

    // 普通上传头像
    public function uploadAvatar()
    {
        $param = request::param();
        try {
            $file = request()->file('file');
            $uid = request()->userInfo['user_id'];
            $info = $this->upload($param, $file, 'avatar/' . $uid . '/');
            User::where(['user_id' => $uid])->update(['avatar' => $info['src']]);
            $url = $this->url . $info['src'];
            return success("上传成功", $url);
        } catch (\Exception $e) {
            return error($e->getMessage());
        }
    }

    // 服务器上传头像
    public function uploadLocalAvatar($file, $param, $uid)
    {
        try {
            $info = $this->upload($param, $file, 'avatar/' . $uid . '/', false);
            return $info['src'];
        } catch (\Exception $e) {
            return $e->getMessage() . $e->getLine();
        }
    }

    // 获取图片的尺寸
    protected function getImageSizeInfo($file)
    {
        $extends = [];
        // 如果图片获取图片的尺寸
        $imageSize = getimagesize($file);
        $extends['width'] = $imageSize[0];
        $extends['height'] = $imageSize[1];
        // 如果宽大于高则为横图，宽度填充模式，否则为竖图，高度填充模式
        if ($imageSize[0] >= $imageSize[1]) {
            $extends['fixMode'] = 1;  // 宽度填充
        } else {
            $extends['fixMode'] = 2;  // 高度填充
        }
        if ($imageSize[0] < 200 && $imageSize[1] < 240) {
            $extends['fixMode'] = 3;    // 小图
        }
        return $extends;
    }

    /**
     * 获取文件列表
     * @param  $fileId
     * @return array
     */
    public static function getFileArr($fileId): array
    {
        if (!$fileId) {
            return [];
        }
        $fileArr = self::getInstance()->whereIn('file_id', $fileId)->column('file_id,name,src');
        foreach ($fileArr as &$value) {
            $value['src'] = getDiskUrl() . $value['src'];
        }
        return $fileArr;
    }

    /**
     * 获取文件列表
     * @param $fileIdArr
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getFileArray($fileIdArr): array
    {
        if (!$fileIdArr) {
            return ['file' => [], 'img' => []];
        }
        if (!is_array($fileIdArr)) {
            $fileIdArr = [$fileIdArr];
        }
        $fileArr = [];
        $imgArr = [];
        foreach ($fileIdArr as $fileId) {
            $fileInfo = self::getInstance()->where('file_id', $fileId)->field('file_id,name,src,ext')->find();
            if (!$fileInfo) {
                continue;
            }
            $src = getDiskUrl() . $fileInfo['src'];
            $data = [
                'file_id' => $fileInfo['file_id'],
                'name' => $fileInfo['name'],
                'src' => $src,
            ];
            if (in_array($fileInfo['ext'], ['jpg', 'png'])) {
                array_push($imgArr, $src);
            } else {
                $fileArr[] = $data;
            }
        }
        return ['file' => $fileArr, 'img' => $imgArr];
    }

    /**
     * 获取文件列表
     * @param  $fileId
     * @return array
     */
    public static function getFileInfoBySrc($src)
    {
        if (!$src) {
            return '';
        }
        $fileInfo = self::getInstance()->where('src', $src)->find();
        $fileInfo['full_url'] = getDiskUrl() . $fileInfo['src'];
        return $fileInfo;
    }
}